#ifndef METER_H
#define METER_H

#include <QObject>
#include <QString>
#include <QDateTime>

/**
 * @brief 电表类
 * 封装PM2220电表的数据和状态
 */
class Meter : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int meterId READ meterId NOTIFY meterIdChanged)
    Q_PROPERTY(QString name READ name NOTIFY nameChanged)
    Q_PROPERTY(QString location READ location NOTIFY locationChanged)
    Q_PROPERTY(int busId READ busId NOTIFY busIdChanged)
    Q_PROPERTY(bool online READ isOnline WRITE setOnline NOTIFY onlineChanged)
    Q_PROPERTY(double ua READ ua WRITE setUa NOTIFY dataUpdated)
    Q_PROPERTY(double ub READ ub WRITE setUb NOTIFY dataUpdated)
    Q_PROPERTY(double uc READ uc WRITE setUc NOTIFY dataUpdated)
    Q_PROPERTY(double ia READ ia WRITE setIa NOTIFY dataUpdated)
    Q_PROPERTY(double ib READ ib WRITE setIb NOTIFY dataUpdated)
    Q_PROPERTY(double ic READ ic WRITE setIc NOTIFY dataUpdated)
    Q_PROPERTY(QDateTime lastUpdateTime READ lastUpdateTime NOTIFY lastUpdateTimeChanged)
    Q_PROPERTY(int failureCount READ failureCount NOTIFY failureCountChanged)

public:
    explicit Meter(QObject *parent = nullptr);
    Meter(int meterId, const QString &name, int busId, QObject *parent = nullptr);
    Meter(int meterId, const QString &name, const QString &location, int busId, QObject *parent = nullptr);
    ~Meter();

    // Getter 方法
    int meterId() const { return m_meterId; }
    QString name() const { return m_name; }
    QString location() const { return m_location; }
    int busId() const { return m_busId; }
    bool isOnline() const { return m_online; }
    double ua() const { return m_ua; }
    double ub() const { return m_ub; }
    double uc() const { return m_uc; }
    double ia() const { return m_ia; }
    double ib() const { return m_ib; }
    double ic() const { return m_ic; }
    QDateTime lastUpdateTime() const { return m_lastUpdateTime; }
    int failureCount() const { return m_failureCount; }

    // Setter 方法
    void setOnline(bool online);
    void setUa(double value);
    void setUb(double value);
    void setUc(double value);
    void setIa(double value);
    void setIb(double value);
    void setIc(double value);

    /**
     * @brief 更新电表数据（从Modbus寄存器数据）
     * @param registers 寄存器数据数组（6个寄存器）
     * 寄存器映射：
     * [0]: Ua (0.1V)
     * [1]: Ub (0.1V)
     * [2]: Uc (0.1V)
     * [3]: Ia (0.001A)
     * [4]: Ib (0.001A)
     * [5]: Ic (0.001A)
     */
    void updateFromRegisters(const QVector<quint16> &registers);

    /**
     * @brief 计算三相平均电压
     * @return 平均电压（V）
     */
    double averageVoltage() const;

    /**
     * @brief 计算三相平均电流
     * @return 平均电流（A）
     */
    double averageCurrent() const;

    /**
     * @brief 计算总功率（简化计算，假设功率因数为1）
     * @return 总功率（W）
     */
    double totalPower() const;

    /**
     * @brief 重置失败计数
     */
    void resetFailureCount();

    /**
     * @brief 检查是否超时离线（超过指定时间未更新）
     * @param timeoutSeconds 超时时间（秒），默认10秒
     * @return 是否超时离线
     */
    bool isTimeout(int timeoutSeconds = 10) const;

signals:
    void meterIdChanged();        /**< 电表ID改变信号 */
    void nameChanged();           /**< 电表名称改变信号 */
    void locationChanged();       /**< 电表位置改变信号 */
    void busIdChanged();          /**< 总线ID改变信号 */
    void onlineChanged();         /**< 在线状态改变信号 */
    void lastUpdateTimeChanged(); /**< 最后更新时间改变信号 */
    void failureCountChanged();   /**< 失败计数改变信号 */

    /**
     * @brief 数据更新信号（所有数据更新后发送，包含电压电流变化）
     */
    void dataUpdated();

private:
    int m_meterId;              ///< 电表ID（站号：1-120）
    QString m_name;             ///< 电表名称
    QString m_location;         ///< 电表位置（如：配电室A-1号柜）
    int m_busId;                ///< 总线ID（1-3对应3个配电室）
    bool m_online;              ///< 在线状态
    double m_ua;                ///< A相电压（V）
    double m_ub;                ///< B相电压（V）
    double m_uc;                ///< C相电压（V）
    double m_ia;                ///< A相电流（A）
    double m_ib;                ///< B相电流（A）
    double m_ic;                ///< C相电流（A）
    QDateTime m_lastUpdateTime; ///< 最后更新时间
    int m_failureCount;         ///< 连续失败次数
};

#endif // METER_H
